package com.congee02.modelshellmvn.service;

import com.congee02.modelshellmvn.entity.account.Account;
import com.congee02.modelshellmvn.entity.account.AccountRoleDefinition;
import com.congee02.modelshellmvn.exception.AccountLoginFailed;
import com.congee02.modelshellmvn.exception.AccountRegisterFailed;
import com.congee02.modelshellmvn.exception.DuplicateUsernameException;
import com.congee02.modelshellmvn.manager.token.AccountJwtSigner;
import com.congee02.modelshellmvn.manager.token.AccountJwtValidator;
import com.congee02.modelshellmvn.repo.account.AccountRepository;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.util.Optional;

@Service
public class AccountService {

    @Resource
    private AccountRepository accountRepository;

    @Resource
    private AccountJwtSigner signer;

    @Resource
    private AccountJwtValidator validator;

    /**
     * 登录
     * @param account   账户登录信息
     * @return          数据库存储的账户信息
     */
    public Account login(Account account) {

        String username = account.getUsername();
        String password = account.getPassword();

        if (username == null || password == null) {
            throw new AccountLoginFailed();
        }

        Optional<Account> accountOptional = accountRepository.findByUsernameAndPassword(username, password);

        Account returnAccount = accountOptional.orElseThrow(
                AccountLoginFailed::new
        );

        signer.signJwt(
                returnAccount
        );

        return returnAccount;
    }

    /**
     * @param account   账户登录信息
     * @return          数据库新增的账户信息
     */
//    @Transactional
    public Account register(Account account) {
        String username = account.getUsername();
        String password = account.getPassword();

        if (username == null || password == null) {
            throw new AccountRegisterFailed();
        }

        if (accountRepository.findByUsername(username).isPresent()) {
            throw new DuplicateUsernameException();
        }

        account.setRole(AccountRoleDefinition.DEFAULT_ROLE);

        Account savedAccount = accountRepository.save(account);

        return savedAccount.setPassword(null);
    }


    public Account current(Account account) {
        if (account == null || account.getJwt() == null) {
            return null;
        }
        return validator.tryExtractInfo(
                account
        );
    }
}
